package snmpstatistics;

import java.awt.BasicStroke;
import java.awt.Color;
import java.util.LinkedList;

import javax.swing.JPanel;

import org.jfree.chart.ChartFactory;
import org.jfree.chart.ChartPanel;
import org.jfree.chart.JFreeChart;
import org.jfree.chart.axis.NumberAxis;
import org.jfree.chart.plot.CategoryPlot;
import org.jfree.chart.plot.PlotOrientation;
import org.jfree.chart.renderer.category.LineAndShapeRenderer;
import org.jfree.data.category.CategoryDataset;
import org.jfree.data.category.DefaultCategoryDataset;

import snmpstatistics.StatsToShow.Statistics;

public class Graph extends JPanel {
	private static final long serialVersionUID = -6338472990204176185L;

	private static final int NUM_STATS = 20;
	
	private ChartPanel chartPanel;
	
	private LinkedList<SNMPStats> lstStats = new LinkedList<SNMPStats>();

	private StatsToShow statsToShow;
	
	// row keys...
	private final static String[] rowSeries = {"Bad Values", "Gen Errs", "GetNexts", "GetRequests", "GetResponses", "No Such Names", "Packets", "SetRequests", "Too Bigs", "Traps", "In PDU Error", "Out PDU Error", "inPackets/s", "outPackets/s"};

	private static int POLLING_TIME_IN_SECOND = 1;
	
	public Graph(StatsToShow statsToShow, long polling_time) {
		super();
		this.statsToShow = statsToShow;
		POLLING_TIME_IN_SECOND = (int) polling_time/1000;
		for (int i = 0; i < NUM_STATS; i++) {
			lstStats.add(new SNMPStats());
		}
		initialize();
	}
	
	private void initialize() {
		JFreeChart chart = createChart(createDataset());

		// add the chart to a panel...
		chartPanel = new ChartPanel(chart);
		chartPanel.setPreferredSize(new java.awt.Dimension(500, 270));
//		setContentPane(chartPanel);
		
		removeAll();
		add(chartPanel);
	}

	public void addStats(SNMPStats stats) {
		lstStats.addLast(stats);

		while (lstStats.size() > NUM_STATS)
			lstStats.removeFirst();
		
		initialize();
	}

	private DefaultCategoryDataset createDataset() {		 
		// create the dataset...
		DefaultCategoryDataset dataset = new DefaultCategoryDataset();
		if(statsToShow.isEnabled(Statistics.TOTAL_IN_PACKETS) || 
				statsToShow.isEnabled(Statistics.TOTAL_OUT_PACKETS)){
			for (int i = 1; i < NUM_STATS; i++) {
				String key = i + "";
				SNMPStats precedentStats = lstStats.get(i-1);
				SNMPStats currentStats = lstStats.get(i);
				
				int totalInPkts = 0;
				if(precedentStats.getTotalInPkts() != 0)
					totalInPkts = currentStats.getTotalInPkts() - precedentStats.getTotalInPkts();
				
				int totalOutPkts = 0;
				if(precedentStats.getTotalOutPkts() != 0)
					totalOutPkts = currentStats.getTotalOutPkts() - precedentStats.getTotalOutPkts();
				
				if(statsToShow.isEnabled(Statistics.TOTAL_IN_PACKETS))
					dataset.addValue((totalInPkts)/POLLING_TIME_IN_SECOND, 		rowSeries[12], key);
				if(statsToShow.isEnabled(Statistics.TOTAL_OUT_PACKETS))
					dataset.addValue((totalOutPkts)/POLLING_TIME_IN_SECOND, 		rowSeries[13], key);
			}
		}
		else {		
			for (int i = 0; i < NUM_STATS; i++) {
				String key = i + "";//columnKeys[i];
				SNMPStats stats = lstStats.get(i);
				
				if(statsToShow.isEnabled(Statistics.BAD_VALUES))
					dataset.addValue(stats.getRateBadValues(), 		rowSeries[0], key);
				if(statsToShow.isEnabled(Statistics.GEN_ERR))
					dataset.addValue(stats.getRateGenErrs(), 		rowSeries[1], key);
				if(statsToShow.isEnabled(Statistics.GET_NEXT))
					dataset.addValue(stats.getRateGetNexts(), 		rowSeries[2], key);
				if(statsToShow.isEnabled(Statistics.GET_REQUEST))
					dataset.addValue(stats.getRateGetRequests(), 	rowSeries[3], key);
				if(statsToShow.isEnabled(Statistics.GET_RESPONSE))
					dataset.addValue(stats.getRateGetResponses(), 	rowSeries[4], key);
				if(statsToShow.isEnabled(Statistics.NO_SUCH_NAME))
					dataset.addValue(stats.getRateNoSuchNames(), 	rowSeries[5], key);
				if(statsToShow.isEnabled(Statistics.PACKETS))
					dataset.addValue(stats.getRatePkts(), 			rowSeries[6], key);
				if(statsToShow.isEnabled(Statistics.SET_REQUEST))
					dataset.addValue(stats.getRateSetRequests(), 	rowSeries[7], key);
				if(statsToShow.isEnabled(Statistics.TOO_BIG))
					dataset.addValue(stats.getRateTooBigs(), 		rowSeries[8], key);
				if(statsToShow.isEnabled(Statistics.TRAPS))
					dataset.addValue(stats.getRateTraps(), 			rowSeries[9], key);
				if(statsToShow.isEnabled(Statistics.IN_PDU_ERROR_RATE))
					dataset.addValue(stats.getInPDUErrorRate(), 		rowSeries[10], key);
				if(statsToShow.isEnabled(Statistics.OUT_PDU_ERROR_RATE))
					dataset.addValue(stats.getOutPDUErrorRate(), 		rowSeries[11], key);
			}
		}
		
//		dataset.addValue(8.0, rowSeries[0], columnKeys[0]);
//		dataset.addValue(1.0, rowSeries[0], columnKeys[1]);
//		dataset.addValue(4.0, rowSeries[0], columnKeys[2]);
//		dataset.addValue(3.0, rowSeries[0], columnKeys[3]);
//		dataset.addValue(5.0, rowSeries[0], columnKeys[4]);
//		dataset.addValue(5.0, rowSeries[0], columnKeys[5]);
//		dataset.addValue(7.0, rowSeries[0], columnKeys[6]);
//		dataset.addValue(7.0, rowSeries[0], columnKeys[7]);
//
//		dataset.addValue(5.0, rowSeries[1], columnKeys[1]);
//		dataset.addValue(7.0, rowSeries[1], columnKeys[2]);
//		dataset.addValue(6.0, rowSeries[1], columnKeys[3]);
//		dataset.addValue(8.0, rowSeries[1], columnKeys[4]);
//		dataset.addValue(4.0, rowSeries[1], columnKeys[5]);
//		dataset.addValue(4.0, rowSeries[1], columnKeys[6]);
//		dataset.addValue(2.0, rowSeries[1], columnKeys[7]);
//		dataset.addValue(1.0, rowSeries[1], columnKeys[8]);
//
//		dataset.addValue(4.0, rowSeries[2], columnKeys[1]);
//		dataset.addValue(3.0, rowSeries[2], columnKeys[2]);
//		dataset.addValue(2.0, rowSeries[2], columnKeys[3]);
//		dataset.addValue(3.0, rowSeries[2], columnKeys[4]);
//		dataset.addValue(6.0, rowSeries[2], columnKeys[5]);
//		dataset.addValue(3.0, rowSeries[2], columnKeys[6]);
//		dataset.addValue(4.0, rowSeries[2], columnKeys[7]);
//		dataset.addValue(3.0, rowSeries[2], columnKeys[8]);
		
		return dataset;

	}

	@SuppressWarnings("deprecation")
	private JFreeChart createChart(CategoryDataset dataset) {

		// create the chart...
		JFreeChart chart = ChartFactory.createLineChart("", // chart
				// title
				"", // domain axis label
				"", // range axis label
				dataset, // data
				PlotOrientation.VERTICAL, // orientation
				true, // include legend
				true, // tooltips
				false // urls
				);
		// NOW DO SOME OPTIONAL CUSTOMISATION OF THE CHART...
		// LegendTitle legend = chart.getLegend();
		// legend.setDisplaySeriesShapes(true);

		chart.setBackgroundPaint(new Color(0xCC, 0xCC, 0xFF));

		CategoryPlot plot = chart.getCategoryPlot();

		// customise the domain axis...
//		CategoryAxis domainAxis = plot.getDomainAxis();
//		domainAxis.VerticalCategoryLabels(true);

		// customise the range axis...
		NumberAxis rangeAxis = (NumberAxis) plot.getRangeAxis();
		rangeAxis.setStandardTickUnits(NumberAxis.createIntegerTickUnits());
		rangeAxis.setAutoRangeIncludesZero(true);
		rangeAxis.setUpperMargin(0.20);
		rangeAxis.setLabelAngle(Math.PI / 2.0);

		// customise the renderer...
		LineAndShapeRenderer renderer = (LineAndShapeRenderer) plot
				.getRenderer();
		// renderer.setDrawShapes(true);

		renderer.setSeriesStroke(0, new BasicStroke(2.0f,
				BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f,
				new float[] { 10.0f, 6.0f }, 0.0f));
		renderer.setSeriesStroke(1, new BasicStroke(2.0f,
				BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f,
				new float[] { 6.0f, 6.0f }, 0.0f));
		renderer.setSeriesStroke(2, new BasicStroke(2.0f,
				BasicStroke.CAP_ROUND, BasicStroke.JOIN_ROUND, 1.0f,
				new float[] { 2.0f, 6.0f }, 0.0f));

		renderer.setItemLabelsVisible(true);
		// OPTIONAL CUSTOMISATION COMPLETED.

		return chart;
	}
}
